﻿#define _CRT_SECURE_NO_WARNINGS
#include "Class.h"
using namespace std;

//2.类的引入
//C语言结构体中只能定义变量，在C++中，结构体内不仅可以定义变量，也可以定义函数。
//比如：之前在数据结构初阶中，用C语言方式实现的栈，结构体中只能定义变量；
//现在以C++方式实现，会发现struct中也可以定义函数。

////C++兼容C语言，结构用法可以继续使用
////同时struct也升级成了类
//struct Stack { //C++的类
//	//成员函数（类的方法）
//	void Init() { //可以不用参数
//		a = nullptr;
//		top = capacity = 0;
//	}
//
//	void Push(int x) {}
//
//	//成员变量（类的属性）
//	int* a;
//	int top;
//	int capacity;
//};
//
//void StackInit(struct Stack* ps) {} //C语言的函数
//void StackPush(struct Stack* ps, int x) {}
//
//int main() {
//	struct Stack st1;//C语言方式定义结构体
//	StackInit(&st1);
//	StackPush(&st1, 1);
//
//	Stack st2;//C++方式定义结构体（C语言不允许该方法）这里是类
//	st2.Init();
//	st2.Push(1);
//}



//3.类的定义
//类的两种定义方式：
//1. 声明和定义全部放在类体中，需注意：成员函数如果在类中定义，编译器可能会将其当成内联函数处理。
//2. 类声明放在.h文件中，成员函数定义放在.cpp文件中，注意：成员函数名前需要加类名::



////4.类的访问限定符及封装
////C++实现封装的方式：用类将对象的属性与方法结合在一块，让对象更加完善，
////通过访问权限选择性的将其接口提供给外部的用户使用
//
////【访问限定符说明】
////1. public修饰的成员在类外可以直接被访问
////2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
////3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
////4. 如果后面没有访问限定符，作用域就到 } 即类结束。
////5. class的默认访问权限为private，struct为public(因为struct要兼容C)
////注意：访问限定符只在编译时有用，当数据映射到内存后，没有任何访问限定符上的区别
//class Stack { 
//public:
//	//成员函数（类的方法）
//	void Init() { //可以不用参数
//		a = nullptr;
//		top = capacity = 0;
//	}
//
//	void Push(int x) {
//		if (top == capacity) {
//			int newcapacity = capacity == 0 ? 4 : capacity * 2;
//			a = (int*)realloc(a, sizeof(int) * newcapacity);
//			capacity = newcapacity;
//		}
//		a[top++] = x;
//	}
//
//	int Top() {
//		return a[top - 1];
//	}
//
//private: //访问限定符（私有）
//	//成员变量（类的属性）
//	int* a;
//	int top;
//	int capacity;
//};
//
//int main() {
//	Stack st;
//	st.Init();
//	st.Push(1);
//	//cout << st.a[st.top - 1] << endl;//访问成员变量时，不确定top指向哪
//	cout << st.Top() << endl;
//}

////成员变量命名规则的建议：
//class Date {
//public:
//	void Init(int year) {
//		//year = year;// 这里的year到底是成员变量，还是函数形参？
//		_year = year;
//	}
//	
//
//private:
//	//int year;
//	int _year;
//};



//5.类的作用域
//类定义了一个新的作用域，类的所有成员都在类的作用域中。
//在类体外定义成员时，需要使用 ::作用域操作符指明成员属于哪个类域。



//6.类的实例化
//用类类型创建对象的过程，称为类的实例化
//1. 类是对对象进行描述的，是一个模型一样的东西，限定了类有哪些成员，定义出一个类并没有分配实际的内存空间来存储它；
//比如：入学时填写的学生信息表，表格就可以看成是一个类，来描述具体学生信息。
class Date {
public:
	void Init(int year) {
		_year = year;
	}

private:
	int _year;//声明
};

int main() {
	//下方错误访问方法
	//Date._year;
	//Date::_year;
	Date d1;
	d1.Init(2024);

	cout << sizeof(Date) << endl; //4
	cout << sizeof(d1) << endl;//4
	//说明函数没有占用空间
	//每个对象中成员变量是不同的，但是调用同一份函数，如果按照此种方式存储，
	//当一个类创建多个对象时，每个对象中都会保存一份代码，相同代码保存多次，浪费空间。
	//那么如何解决呢？
	//只保存成员变量，成员函数存放在公共的代码段
}